home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch12 / Geometry.bas < prev    next >
Encoding:
BASIC Source File  |  1999-06-18  |  3.0 KB  |  101 lines

  1. Attribute VB_Name = "Geometry"
  2. Option Explicit
  3.  
  4. Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
  5. Private Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal X As Long, ByVal Y As Long) As Long
  6. Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
  7. Private Const ALTERNATE = 1
  8. Private Const WINDING = 2
  9.  
  10. ' Find the distance from the point (x1, y1) to the
  11. ' line passing through (x1, y1) and (x2, y2).
  12. Public Function DistPointToLine(ByVal A As Single, ByVal B As Single, ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single) As Single
  13. Dim vx As Single
  14. Dim vy As Single
  15. Dim t As Single
  16. Dim dx As Single
  17. Dim dy As Single
  18. Dim close_x As Single
  19. Dim close_y As Single
  20.  
  21.     ' Get the vector component for the segment.
  22.     ' The segment is given by:
  23.     '       x(t) = x1 + t * vx
  24.     '       y(t) = y1 + t * vy
  25.     ' where 0.0 <= t <= 1.0
  26.     vx = x2 - x1
  27.     vy = y2 - y1
  28.  
  29.     ' Find the best t value.
  30.     If (vx = 0) And (vy = 0) Then
  31.         ' The points are the same. There is no segment.
  32.         t = 0
  33.     Else
  34.         ' Calculate the minimal value for t.
  35.         t = -((x1 - A) * vx + (y1 - B) * vy) / (vx * vx + vy * vy)
  36.     End If
  37.  
  38.     ' Keep the point on the segment.
  39.     If t < 0# Then
  40.         t = 0#
  41.     ElseIf t > 1# Then
  42.         t = 1#
  43.     End If
  44.  
  45.     ' Set the return values.
  46.     close_x = x1 + t * vx
  47.     close_y = y1 + t * vy
  48.     dx = A - close_x
  49.     dy = B - close_y
  50.     DistPointToLine = Sqr(dx * dx + dy * dy)
  51. End Function
  52. ' Return True if the polygon is at this location.
  53. Public Function PolygonIsAt(ByVal is_closed As Boolean, ByVal X As Single, ByVal Y As Single, points() As POINTAPI) As Boolean
  54. Const HIT_DIST = 3
  55. Dim start_i As Integer
  56. Dim i As Integer
  57. Dim num_points As Integer
  58. Dim x1 As Single
  59. Dim y1 As Single
  60. Dim x2 As Single
  61. Dim y2 As Single
  62. Dim dist As Single
  63.  
  64.     PolygonIsAt = False
  65.  
  66.     num_points = UBound(points)
  67.     If is_closed Then
  68.         x2 = points(num_points).X
  69.         y2 = points(num_points).Y
  70.         start_i = 1
  71.     Else
  72.         x2 = points(1).X
  73.         y2 = points(1).Y
  74.         start_i = 2
  75.     End If
  76.  
  77.     ' Check each segment in the Polyline.
  78.     For i = start_i To num_points
  79.         With points(i)
  80.             x1 = .X
  81.             y1 = .Y
  82.         End With
  83.         dist = DistPointToLine(X, Y, x1, y1, x2, y2)
  84.         If dist <= HIT_DIST Then
  85.             PolygonIsAt = True
  86.             Exit For
  87.         End If
  88.         x2 = x1
  89.         y2 = y1
  90.     Next i
  91. End Function
  92. ' Return True if the point is inside the polygon.
  93. Public Function PointIsInPolygon(ByVal X As Single, ByVal Y As Single, points() As POINTAPI) As Boolean
  94. Dim polygon_region As Long
  95.  
  96.     polygon_region = CreatePolygonRgn(points(1), UBound(points), ALTERNATE)
  97.     PointIsInPolygon = PtInRegion(polygon_region, X, Y)
  98.     DeleteObject polygon_region
  99. End Function
  100.  
  101.